﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using System.Windows.Media;

namespace GraphicsDesigner
{
    public class Cube : Shapes
    {
        #region Private Members

        Point3D p0;
        Point3D p1;
        Point3D p2;
        Point3D p3;
        Point3D p4;
        Point3D p5;
        Point3D p6;
        Point3D p7;


        #endregion

        #region Private Methods

        //private void InitializePoints(int size)
        //{
        //    p0 = new Point3D(0, 0, 0);
        //    p1 = new Point3D(size, 0, 0);
        //    p2 = new Point3D(size, 0, size);
        //    p3 = new Point3D(0, 0, size);
        //    p4 = new Point3D(0, size, 0);
        //    p5 = new Point3D(size, size, 0);
        //    p6 = new Point3D(size, size, size);
        //    p7 = new Point3D(0, size, size);
        //}

        private Model3DGroup CreateTriangleModel(Point3D p0, Point3D p1, Point3D p2, Color color)
        {
            MeshGeometry3D mesh = new MeshGeometry3D();
            mesh.Positions.Add(p0);
            mesh.Positions.Add(p1);
            mesh.Positions.Add(p2);

            mesh.TriangleIndices.Add(0);
            mesh.TriangleIndices.Add(1);
            mesh.TriangleIndices.Add(2);


            Vector3D normal = CalculateNormal(p0, p1, p2);
            mesh.Normals.Add(normal);
            mesh.Normals.Add(normal);
            mesh.Normals.Add(normal);

            Material material = new DiffuseMaterial(
                new SolidColorBrush(color));

            GeometryModel3D model = new GeometryModel3D(
                mesh, material);

            Model3DGroup group = new Model3DGroup();
            group.Children.Add(model);
            return group;
        }

        private Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2)
        {
            Vector3D v0 = new Vector3D(
                p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
            Vector3D v1 = new Vector3D(
                p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z);
            return Vector3D.CrossProduct(v0, v1);
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Draws a cube with the specified size.
        /// </summary>
        /// <param name="size">The size.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public ModelVisual3D Draw(int size, Color color, int x, int y, int z)
        {
            Model3DGroup cube = new Model3DGroup();

            // InitializePoints(size);


            //p0 = new Point3D(0, 0, 0);
            //p1 = new Point3D(size, 0, 0);
            //p2 = new Point3D(size, 0, size);
            //p3 = new Point3D(0, 0, size);
            //p4 = new Point3D(0, size, 0);
            //p5 = new Point3D(size, size, 0);
            //p6 = new Point3D(size, size, size);
            //p7 = new Point3D(0, size, size);

            p0 = new Point3D(x, y, z);
            p1 = new Point3D(size, y, z);
            p2 = new Point3D(size, y, size);
            p3 = new Point3D(x, y, size);
            p4 = new Point3D(x, size, z);
            p5 = new Point3D(size, size, z);
            p6 = new Point3D(size, size, size);
            p7 = new Point3D(x, size, size);


            //front side triangles
            cube.Children.Add(CreateTriangleModel(p3, p2, p6, color));
            cube.Children.Add(CreateTriangleModel(p3, p6, p7, color));

            //right side triangles                           
            cube.Children.Add(CreateTriangleModel(p2, p1, p5, color));
            cube.Children.Add(CreateTriangleModel(p2, p5, p6, color));

            //back side triangles                            
            cube.Children.Add(CreateTriangleModel(p1, p0, p4, color));
            cube.Children.Add(CreateTriangleModel(p1, p4, p5, color));

            //left side triangles
            cube.Children.Add(CreateTriangleModel(p0, p3, p7, color));
            cube.Children.Add(CreateTriangleModel(p0, p7, p4, color));

            //top side triangles
            cube.Children.Add(CreateTriangleModel(p7, p6, p5, color));
            cube.Children.Add(CreateTriangleModel(p7, p5, p4, color));

            //bottom side triangles
            cube.Children.Add(CreateTriangleModel(p2, p3, p0, color));
            cube.Children.Add(CreateTriangleModel(p2, p0, p1, color));

            ModelVisual3D model = new ModelVisual3D();
            model.Content = cube;
            return model;
            //this.mainViewport.Children.Add(model);
        }

        public ModelVisual3D TestDraw(int size, Color color, int x, int y, int z)
        {
            Model3DGroup cube = new Model3DGroup();

            // InitializePoints(size);


            //p0 = new Point3D(0, 0, 0);
            //p1 = new Point3D(size, 0, 0);
            //p2 = new Point3D(size, 0, size);
            //p3 = new Point3D(0, 0, size);
            //p4 = new Point3D(0, size, 0);
            //p5 = new Point3D(size, size, 0);
            //p6 = new Point3D(size, size, size);
            //p7 = new Point3D(0, size, size);

            p0 = new Point3D(x, y, z);
            p1 = new Point3D(size, y, z);
            p2 = new Point3D(size, y, size);
            p3 = new Point3D(x, y, size);
            p4 = new Point3D(x, size, z);
            p5 = new Point3D(size, size, z);
            p6 = new Point3D(size, size, size);
            p7 = new Point3D(x, size, size);


            //front side triangles
            cube.Children.Add(CreateTriangleModel(p3, p2, p6, color));
            cube.Children.Add(CreateTriangleModel(p3, p6, p7, color));

            //right side triangles                           
            cube.Children.Add(CreateTriangleModel(p2, p1, p5, color));
            cube.Children.Add(CreateTriangleModel(p2, p5, p6, color));

            //back side triangles                            
            cube.Children.Add(CreateTriangleModel(p1, p0, p4, color));
            cube.Children.Add(CreateTriangleModel(p1, p4, p5, color));

            //left side triangles
            cube.Children.Add(CreateTriangleModel(p0, p3, p7, color));
            cube.Children.Add(CreateTriangleModel(p0, p7, p4, color));

            //top side triangles
            cube.Children.Add(CreateTriangleModel(p7, p6, p5, color));
            cube.Children.Add(CreateTriangleModel(p7, p5, p4, color));

            //bottom side triangles
            cube.Children.Add(CreateTriangleModel(p2, p3, p0, color));
            cube.Children.Add(CreateTriangleModel(p2, p0, p1, color));

            ModelVisual3D model = new ModelVisual3D();
            model.Content = cube;
            return model;
            //this.mainViewport.Children.Add(model);
        }
        #endregion

    }
}
